using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace marqueecontrol
{
    public class Marquee : ContentControl
    {
        private bool IsLoaded;
        private readonly Storyboard storyboard = new Storyboard();
        private readonly DoubleAnimation doubleAnimation = new DoubleAnimation();
        private FrameworkElement contentPanel;

        public Marquee() {
            DefaultStyleKey = typeof(Marquee);
        }

        public override void OnApplyTemplate() {
            base.OnApplyTemplate();
            contentPanel = GetTemplateChild("PART_Content") as FrameworkElement;
            Loaded += Marquee_Loaded;
            SizeChanged += Marquee_SizeChanged;
        }

        private void Marquee_SizeChanged(object sender, SizeChangedEventArgs e) {
            RestartAnimation();
        }

        private void Marquee_Loaded(object sender, RoutedEventArgs e) {
            IsLoaded = true;
            RestartAnimation();
            MouseEnter += Marquee_MouseEnter;
            MouseLeave += Marquee_MouseLeave;
        }

        private void Marquee_MouseLeave(object sender, MouseEventArgs e) {
            storyboard.Resume();
        }

        private void Marquee_MouseEnter(object sender, MouseEventArgs e) {
            storyboard.Pause();
        }

        public double Duration {
            get { return (double)GetValue(DurationProperty); }
            set { SetValue(DurationProperty, value); }
        }

        public static readonly DependencyProperty DurationProperty =
            DependencyProperty.Register("Duration", typeof(double), typeof(Marquee), new PropertyMetadata(ValueChanged));

        private static void ValueChanged(object sender, DependencyPropertyChangedEventArgs e) {
            var marquee = (Marquee)sender;
            marquee.RestartAnimation();
        }

        private void RestartAnimation() {
            if (contentPanel == null || !IsLoaded) {
                return;
            }
            if (storyboard.Children.Count != 0) {
                return;
            }

            doubleAnimation.From = ActualWidth;
            doubleAnimation.To = -contentPanel.ActualWidth;
            doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
            doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(Duration / 1000.0 * contentPanel.ActualWidth));

            storyboard.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
            Storyboard.SetTarget(doubleAnimation, contentPanel);
            storyboard.Begin();
        }
    }
}